package cn.chiship.framework.upms.biz.base.service.impl;

import cn.chiship.framework.common.constants.CommonCacheConstants;
import cn.chiship.framework.common.constants.CommonConstants;
import cn.chiship.framework.common.pojo.vo.SystemConfigVo;
import cn.chiship.framework.common.quartz.CronTaskRegistrar;
import cn.chiship.framework.common.quartz.SchedulingRunnable;
import cn.chiship.framework.upms.biz.base.service.UpmsSystemCacheService;
import cn.chiship.framework.upms.biz.system.entity.*;
import cn.chiship.framework.upms.biz.system.mapper.*;
import cn.chiship.framework.upms.biz.system.service.*;
import cn.chiship.sdk.cache.service.RedisService;
import cn.chiship.sdk.core.base.constants.BaseCacheConstants;
import cn.chiship.sdk.core.base.constants.BaseConstants;
import cn.chiship.sdk.framework.pojo.vo.RegionVo;
import cn.chiship.sdk.framework.properties.ChishipDefaultProperties;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author lijian
 */
@Service
public class UpmsSystemCacheServiceImpl implements UpmsSystemCacheService {

	private static final Logger LOGGER = LoggerFactory.getLogger(UpmsSystemCacheServiceImpl.class);

	@Resource
	RedisService redisService;

	@Resource
	ChishipDefaultProperties chishipDefaultProperties;

	@Resource
	CacheUpmsSystemAsyncService cacheUpmsAsyncService;

	@Resource
	UpmsRegionMapper upmsRegionMapper;

	@Resource
	UpmsConfigService upmsConfigService;

	@Resource
	UpmsDataDictMapper upmsDataDictMapper;

	@Resource
	UpmsQuartzJobMapper upmsQuartzJobMapper;

	@Resource
	UpmsAppVersionService upmsAppVersionService;

	@Resource
	UpmsCategoryDictService upmsCategoryDictService;

	@Override
	public void cacheConfigs() {
		upmsConfigService.cacheConfigs();
	}

	@Override
	public void cacheProofs() {
		String key = CommonCacheConstants.buildKey(BaseCacheConstants.REDIS_PROOF_PREFIX);
		redisService.del(key);

		JSONObject proof = new JSONObject();
		proof.put("projectId", chishipDefaultProperties.getId());
		proof.put("publicKey", chishipDefaultProperties.getPublicKey());
		proof.put("privateKey", chishipDefaultProperties.getPrivateKey());
		proof.put("signKey", chishipDefaultProperties.getSignKey());
		proof.put("appSecret", chishipDefaultProperties.getAppSecret());
		proof.put("appKey", chishipDefaultProperties.getAppKey());
		proof.put("appId", chishipDefaultProperties.getAppId());
		redisService.set(key, proof);

	}

	@Override
	public void cacheDataDict() {
		UpmsDataDictExample upmsDataDictExample = new UpmsDataDictExample();
		upmsDataDictExample.createCriteria().andIsDeletedEqualTo(BaseConstants.NO).andPidIsNotNull();
		List<UpmsDataDict> upmsDataDicts = upmsDataDictMapper.selectByExample(upmsDataDictExample);

		String dataDictItemKey = CommonCacheConstants.buildKey(BaseCacheConstants.REDIS_DATA_DICT_ITEM_PREFIX);
		redisService.del(dataDictItemKey);
		Map<String, String> dataDictCodeMap = Maps.newHashMapWithExpectedSize(7);
		Map<String, List<UpmsDataDict>> mapData = Maps.newHashMapWithExpectedSize(7);
		for (UpmsDataDict upmsDataDict : upmsDataDicts) {
			if ("0".equals(upmsDataDict.getPid())) {
				dataDictCodeMap.put(upmsDataDict.getId(), upmsDataDict.getDataDictCode());
				mapData.put(upmsDataDict.getDataDictCode(), new ArrayList<>());
			}
		}
		for (Map.Entry<String, String> entry : dataDictCodeMap.entrySet()) {
			String pid = entry.getKey();
			String code = entry.getValue();
			List<UpmsDataDict> upmsDataDictItemList = mapData.get(code);
			for (UpmsDataDict upmsDataDict : upmsDataDicts) {
				if (upmsDataDict.getPid().equals(pid)) {
					upmsDataDictItemList.add(upmsDataDict);
				}
			}
			mapData.put(code, upmsDataDictItemList);
			redisService.hset(dataDictItemKey, code, mapData.get(code));
		}
	}

	@Override
	public void cacheRegions() {
		String key = CommonCacheConstants.buildKey(BaseCacheConstants.REDIS_REGIONS_PREFIX);
		redisService.removeAll(key);
		UpmsRegionExample regionExample = new UpmsRegionExample();
		regionExample.createCriteria().andPidEqualTo(CommonConstants.PROVINCE_PID);
		/**
		 * 省
		 */
		List<UpmsRegion> provinces = upmsRegionMapper.selectByExample(regionExample);

		List<RegionVo> provinceVos = new ArrayList<>();
		for (UpmsRegion province : provinces) {
			RegionVo regionVo = new RegionVo();
			BeanUtils.copyProperties(province, regionVo);
			redisService.set(CommonCacheConstants.buildKey(CommonCacheConstants.REDIS_REGION_ITEM_PREFIX) + ":"
					+ regionVo.getId(), regionVo);
			provinceVos.add(regionVo);
		}

		redisService.hset(key, String.valueOf(CommonConstants.PROVINCE_PID), provinceVos);

		regionExample = new UpmsRegionExample();
		regionExample.createCriteria().andPidNotEqualTo(CommonConstants.PROVINCE_PID);
		List<UpmsRegion> regions = upmsRegionMapper.selectByExample(regionExample);

		for (UpmsRegion province : provinces) {
			cacheUpmsAsyncService.cacheRegionsCity(province.getId(), regions);
		}
	}

	@Resource
	private CronTaskRegistrar cronTaskRegistrar;

	@Override
	public void initQuartzJob() {
		UpmsQuartzJobExample upmsQuartzJobExample = new UpmsQuartzJobExample();
		upmsQuartzJobExample.createCriteria().andIsDeletedEqualTo(BaseConstants.NO);
		List<UpmsQuartzJob> upmsQuartzJobs = upmsQuartzJobMapper.selectByExample(upmsQuartzJobExample);
		upmsQuartzJobs.forEach(quartzJob -> {
			if (BaseConstants.NO == quartzJob.getStatus()) {
				SchedulingRunnable task = new SchedulingRunnable(quartzJob.getJobClass(), quartzJob.getJobMethod(),
						quartzJob.getJobParam());
				cronTaskRegistrar.addCronTask(task, quartzJob.getJobCron());
			}
		});
	}

	@Override
	public void cacheApp() {
		List<UpmsAppVersion> appVersions = upmsAppVersionService.listNewsApp();
		String key = CommonCacheConstants.buildKey(CommonCacheConstants.REDIS_APP_VERSION_PREFIX);
		redisService.del(key);
		appVersions.forEach(appVersion -> {
			redisService.hset(key, appVersion.getAppCode(), JSON.parseObject(JSON.toJSONString(appVersion)));
		});
	}

	@Override
	public void cacheCategoryDict() {
		upmsCategoryDictService.cacheCategoryDict();
	}

}
